#ifndef TERRAIN_H_
#define TERRAIN_H_
#include "../generic/Object.h"
#include "../generic/Color.h"
#include "../generic/Vertex.h"
//#include "Water.h"

#define HEIGHT_COUNT 256
#define TEXTURE_TERRAIN_COUNT 10

struct Region {
	int min;
	int max;
	int optimal;
	float r, g, b;
	
	Region(int min, int max, float r, float g, float b) {
		this->min = min;
		this->max = max;
		this->r = r;
		this->g = g;
		this->b = b;
	}
};
class Camera;
class Terrain : public Object
{
public:
	Terrain();
	virtual ~Terrain();

private:
	/* camera */
	Camera* camera;
	
	/* vertex */
	Vertex* vertice; //triangle strip
	int numVertice;
	
	SDL_Surface* surface;
	GLubyte* heightmap;
	int width;
	int height;
	int isInfinite;
	Color3f heightColor[HEIGHT_COUNT];
	GLubyte* generatedTexture;
	int generatedTextureWidth;
	int generatedTextureHeight;
	
	GLubyte* lightTexture;
	
	GLuint* textures;
	GLubyte** tile;
private:
	/* Color / Procedural texture mapping */
	void AllocateTextures();
	
	void CreateTileTextures();
	void LoadTileTextures();
	
	void CreateLightTextures();
	void LoadLightTextures();
	
	void CalculateHeightColor();
	void GetColor(int height);
	Color3i InterpolateTile(int height, int index);
	
	/* Render function */
	void RenderTerrain();
	void RenderInfinite();
	
	/* Light mapping */
	GLubyte* lightmap;
	void CalculateLightmap();
	float GetShade(int height);
	int isLightmapping;
	
public:	
	
	int IsLightmapping();
	void BeginLightmapping();
	void EndLightmapping();
	void ToggleLightmapping();
	
	int GetHeight(Vector3f pos, float& result);
	void GetSize(float & width, float & height);
	
	void LoadHeightMap(char* heightmapFile);	
	void LoadVertice();
	void RenderHeightmap();
	void RenderLightmap();
	void RenderTileTexture();
	void RenderLightTexture();
	
	void Render();
	int IsInfinite();
	void BeginInfinite();
	void EndInfinite();
	
	//Debug functions
	GLvoid* GetPixels();
	void GetTrueSize(int & width, int&  height);
	
	Vector3f TestBoundary(Vector3f pos);
	
	void Update(long time);
/* Water ========================= */
/*
private:
	Water* water;
	int isWaterEnable;	
public:
	void EnableWater();
	void DisableWater();
	int IsWaterEnable();
	void RenderWater();
*/
	
/* Terrain ======================== */
private:
	int isGroundEnable;
public:
	void EnableGround();
	void DisableGround();
	int IsGroundEnable();

protected: // detail map 
	int isDetailMap;

	void LoadDetailMap(const char* file);
	void EnableDetailMap(int enable = 1);

};

#endif /*TERRAIN_H_*/
